<template>
  <div class="reconstruction-container">
    <div class="reconstruction-content">
      <!-- 左侧图片展示区域 -->
      <div class="image-section">
        <div class="section-header">
          <h2>原始图片</h2>
          <div class="image-controls">
            <a-button-group size="small">
              <a-button @click="prevImage" :disabled="currentImageIndex === 0">
                <template #icon><icon-left /></template>
                上一张
              </a-button>
              <a-button @click="nextImage" :disabled="currentImageIndex === totalImages - 1">
                下一张
                <template #icon><icon-right /></template>
              </a-button>
            </a-button-group>
            <span class="image-counter">{{ currentImageIndex + 1 }} / {{ totalImages }}</span>
          </div>
        </div>
        
        <div class="image-display">
          <div class="current-image">
            <img 
              :src="currentImagePath" 
              :alt="`图片 ${currentImageIndex + 1}`"
              @load="onImageLoad"
              @error="onImageError"
            />
            <div class="image-info">
              <p>{{ currentImageName }}</p>
            </div>
          </div>
          
          <!-- 图片缩略图列表 -->
          <div class="thumbnail-list">
            <div 
              v-for="(image, index) in visibleThumbnails" 
              :key="index"
              class="thumbnail-item"
              :class="{ active: index === currentImageIndex }"
              @click="selectImage(index)"
            >
              <img :src="image.path" :alt="`缩略图 ${index + 1}`" />
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧3D模型展示区域 -->
      <div class="model-section">
        <div class="section-header">
          <h2>三维重建结果</h2>
          <div class="model-controls">
            <a-button-group size="small">
              <a-button @click="resetCamera" type="outline">
                <template #icon><icon-refresh /></template>
                重置视角
              </a-button>
              <a-button @click="toggleWireframe" type="outline">
                <template #icon><icon-eye /></template>
                {{ showWireframe ? '实体' : '线框' }}
              </a-button>
              <a-button @click="toggleAnimation" type="outline" v-if="animations.length > 0">
                <template #icon><icon-play-arrow v-if="!isAnimating" /><icon-pause v-else /></template>
                {{ isAnimating ? '暂停' : '播放' }}
              </a-button>
            </a-button-group>
          </div>
        </div>
        
        <div class="model-display">
          <div ref="modelContainer" class="model-container">
            <div class="loading-overlay" v-if="modelLoading">
              <a-spin size="large" />
              <div class="loading-text">{{ loadingText }}</div>
              <div class="loading-progress" v-if="loadingProgress > 0">
                <a-progress 
                  :percent="loadingProgress" 
                  size="small" 
                  :show-text="false"
                  stroke-color="linear-gradient(90deg, #4facfe 0%, #00f2fe 100%)"
                />
                <div class="progress-text">{{ Math.round(loadingProgress) }}%</div>
              </div>
            </div>
          </div>
          
          <div class="model-info">
            <div class="info-item">
              <span class="label">模型文件：</span>
              <span class="value">new.fbx</span>
            </div>
            <div class="info-item">
              <span class="label">重建方式：</span>
              <span class="value">多视图立体视觉</span>
            </div>
            <div class="info-item">
              <span class="label">图片数量：</span>
              <span class="value">{{ totalImages }} 张</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue'
import * as THREE from 'three'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { 
  IconLeft, 
  IconRight, 
  IconRefresh, 
  IconEye, 
  IconPlayArrow, 
  IconPause 
} from '@arco-design/web-vue/es/icon'

// 响应式数据
const modelContainer = ref(null)
const currentImageIndex = ref(0)
const totalImages = ref(152) // Family文件夹中的图片总数
const modelLoading = ref(true)
const loadingText = ref('加载三维模型中...')
const loadingProgress = ref(0)
const showWireframe = ref(false)
const isAnimating = ref(false)
const animations = ref([])

// Three.js 相关变量
let scene, camera, renderer, controls, model, mixer
let animationId

// 计算属性
const currentImagePath = computed(() => {
  const imageNumber = String(currentImageIndex.value + 1).padStart(5, '0')
  return `/Family/${imageNumber}.jpg`
})

const currentImageName = computed(() => {
  const imageNumber = String(currentImageIndex.value + 1).padStart(5, '0')
  return `${imageNumber}.jpg`
})

const visibleThumbnails = computed(() => {
  const thumbnails = []
  const start = Math.max(0, currentImageIndex.value - 5)
  const end = Math.min(totalImages.value, currentImageIndex.value + 6)
  
  for (let i = start; i < end; i++) {
    const imageNumber = String(i + 1).padStart(5, '0')
    thumbnails.push({
      index: i,
      path: `/Family/${imageNumber}.jpg`
    })
  }
  return thumbnails
})

// 图片控制方法
const prevImage = () => {
  if (currentImageIndex.value > 0) {
    currentImageIndex.value--
  }
}

const nextImage = () => {
  if (currentImageIndex.value < totalImages.value - 1) {
    currentImageIndex.value++
  }
}

const selectImage = (index) => {
  currentImageIndex.value = index
}

const onImageLoad = () => {
  // 图片加载成功
}

const onImageError = () => {
  console.warn('图片加载失败:', currentImagePath.value)
}

// 3D模型相关方法
const initThreeJS = () => {
  if (!modelContainer.value) return

  // 创建场景
  scene = new THREE.Scene()
  scene.background = new THREE.Color(0xffffff)

  // 创建相机
  const containerRect = modelContainer.value.getBoundingClientRect()
  camera = new THREE.PerspectiveCamera(75, containerRect.width / containerRect.height, 0.1, 1000)
  camera.position.set(0, 5, 10)

  // 创建渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(containerRect.width, containerRect.height)
  renderer.shadowMap.enabled = true
  renderer.shadowMap.type = THREE.PCFSoftShadowMap
  modelContainer.value.appendChild(renderer.domElement)

  // 创建控制器
  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.05

  // 添加光源
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.6)
  scene.add(ambientLight)

  const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8)
  directionalLight.position.set(10, 10, 5)
  directionalLight.castShadow = true
  scene.add(directionalLight)

  // 加载FBX模型
  loadFBXModel()

  // 开始渲染循环
  animate()
}

const loadFBXModel = () => {
  const loader = new FBXLoader()
  
  loader.load(
    '/reconstruction/new.fbx',
    (fbx) => {
      model = fbx
      
      // 调整模型大小和位置
      const box = new THREE.Box3().setFromObject(model)
      const center = box.getCenter(new THREE.Vector3())
      const size = box.getSize(new THREE.Vector3())
      
      // 将模型居中
      model.position.sub(center)
      
      // 缩放模型以适应视窗
      const maxDim = Math.max(size.x, size.y, size.z)
      const scale = 5 / maxDim
      model.scale.setScalar(scale)
      
      // 设置材质
      model.traverse((child) => {
        if (child.isMesh) {
          child.castShadow = true
          child.receiveShadow = true
          
          if (child.material) {
            child.material.side = THREE.DoubleSide
          }
        }
      })
      
      // 检查动画
      if (fbx.animations && fbx.animations.length > 0) {
        animations.value = fbx.animations
        mixer = new THREE.AnimationMixer(model)
        
        fbx.animations.forEach((clip) => {
          const action = mixer.clipAction(clip)
          action.play()
        })
      }
      
      scene.add(model)
      modelLoading.value = false
      loadingText.value = '模型加载完成'
    },
    (progress) => {
      const percent = (progress.loaded / progress.total) * 100
      loadingProgress.value = percent
      loadingText.value = `加载中... ${Math.round(percent)}%`
    },
    (error) => {
      console.error('模型加载失败:', error)
      modelLoading.value = false
      loadingText.value = '模型加载失败'
    }
  )
}

const animate = () => {
  animationId = requestAnimationFrame(animate)
  
  if (mixer && isAnimating.value) {
    mixer.update(0.016) // 60fps
  }
  
  controls.update()
  renderer.render(scene, camera)
}

const resetCamera = () => {
  if (camera && controls) {
    camera.position.set(0, 5, 10)
    controls.reset()
  }
}

const toggleWireframe = () => {
  if (model) {
    showWireframe.value = !showWireframe.value
    model.traverse((child) => {
      if (child.isMesh && child.material) {
        child.material.wireframe = showWireframe.value
      }
    })
  }
}

const toggleAnimation = () => {
  if (mixer && animations.value.length > 0) {
    isAnimating.value = !isAnimating.value
  }
}

const handleResize = () => {
  if (!modelContainer.value || !camera || !renderer) return
  
  const containerRect = modelContainer.value.getBoundingClientRect()
  camera.aspect = containerRect.width / containerRect.height
  camera.updateProjectionMatrix()
  renderer.setSize(containerRect.width, containerRect.height)
}

// 生命周期钩子
onMounted(() => {
  initThreeJS()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  window.removeEventListener('resize', handleResize)
  
  // 清理Three.js资源
  if (renderer) {
    renderer.dispose()
  }
  if (scene) {
    scene.clear()
  }
})
</script>

<style scoped>
.reconstruction-container {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 20px;
  box-sizing: border-box;
}

.reconstruction-content {
  display: flex;
  gap: 20px;
  height: 100%;
  max-width: 1400px;
  margin: 0 auto;
}

.image-section,
.model-section {
  flex: 1;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(10px);
  display: flex;
  flex-direction: column;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 2px solid #e0e6ff;
}

.section-header h2 {
  margin: 0;
  color: #2c3e50;
  font-size: 1.5rem;
  font-weight: 600;
}

.image-controls,
.model-controls {
  display: flex;
  align-items: center;
  gap: 15px;
}

.image-counter {
  color: #666;
  font-size: 0.9rem;
  min-width: 80px;
  text-align: center;
}

.image-display,
.model-display {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.current-image {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  min-height: 400px;
}

.current-image img {
  max-width: 100%;
  max-height: 70%;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transition: transform 0.3s ease;
}

.current-image img:hover {
  transform: scale(1.02);
}

.image-info {
  margin-top: 15px;
  text-align: center;
}

.image-info p {
  margin: 0;
  color: #666;
  font-size: 0.9rem;
}

.thumbnail-list {
  display: flex;
  gap: 8px;
  padding: 10px;
  background: #f8f9fa;
  border-radius: 8px;
  overflow-x: auto;
  justify-content: center;
}

.thumbnail-item {
  flex-shrink: 0;
  width: 60px;
  height: 60px;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
  border: 2px solid transparent;
  transition: all 0.3s ease;
}

.thumbnail-item:hover {
  border-color: #4facfe;
  transform: scale(1.05);
}

.thumbnail-item.active {
  border-color: #667eea;
  transform: scale(1.1);
}

.thumbnail-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.model-container {
  flex: 1;
  position: relative;
  background: #ffffff;
  border-radius: 8px;
  overflow: hidden;
  min-height: 500px;
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #333;
  z-index: 10;
}

.loading-text {
  margin-top: 20px;
  font-size: 1.1rem;
  color: #333;
}

.loading-progress {
  margin-top: 20px;
  width: 200px;
}

.progress-text {
  text-align: center;
  margin-top: 8px;
  color: #4facfe;
  font-size: 0.9rem;
}

.model-info {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 15px;
  margin-top: 15px;
}

.info-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid #e9ecef;
}

.info-item:last-child {
  border-bottom: none;
}

.info-item .label {
  color: #666;
  font-weight: 500;
}

.info-item .value {
  color: #2c3e50;
  font-weight: 600;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .reconstruction-content {
    flex-direction: column;
    gap: 15px;
  }
  
  .image-section,
  .model-section {
    height: 50vh;
  }
}

@media (max-width: 768px) {
  .reconstruction-container {
    padding: 10px;
  }
  
  .section-header {
    flex-direction: column;
    gap: 10px;
    align-items: flex-start;
  }
  
  .current-image {
    min-height: 300px;
  }
  
  .model-container {
    min-height: 400px;
  }
}
</style>

